#include "test_common.hpp"
#include "tools/api.hpp"
#include <filesystem>
#include <fstream>
#include <thread>
#include <chrono>

namespace fs = std::filesystem;

void test_log_basic()
{
    // 测试基本日志功能
    LOG_NORM("Test normal log");
    LOG_INFO("Test info log");
    LOG_WARNING("Test warning log");
    LOG_ERROR("Test error log");
    
    // 如果能够执行到这里，说明没有崩溃
    ASSERT_TRUE(true);
}

void test_log_format()
{
    int value = 42;
    std::string str = "test";
    LOG_INFO("Test format: value=%d, str=%s", value, str.c_str());
    
    ASSERT_TRUE(true);
}

void test_log_once()
{
    LOG_INFO_ONCE("This should only appear once");
    LOG_INFO_ONCE("This should only appear once");
    LOG_INFO_ONCE("This should only appear once");
    
    ASSERT_TRUE(true);
}

void test_log_ctrl()
{
    // 测试控频日志
    for (int i = 0; i < 10; ++i) {
        LOG_INFO_CTRL(5, "Control frequency log: %d", i);  // 5Hz
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
    }
    
    ASSERT_TRUE(true);
}

void test_save_log()
{
    std::string testDir = test_common::getTestTempDir();
    std::string logFile = testDir + "/test.log";
    test_common::cleanupTestDir(testDir);
    
    MKDIR(testDir);
    SAVE_LOG(logFile);
    SET_SAVE(true);
    
    LOG_INFO("Test log to file");
    
    // 检查文件是否存在
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    ASSERT_TRUE(fs::exists(logFile));
    
    test_common::cleanupTestDir(testDir);
}

void test_log_split_manual()
{
    std::string testDir = test_common::getTestTempDir();
    std::string logFile = testDir + "/test.log";
    test_common::cleanupTestDir(testDir);
    
    MKDIR(testDir);
    SAVE_LOG(logFile);
    SET_SAVE(true);
    SET_LOG_SPLIT(true);
    
    LOG_INFO("Log before split");
    
    // 手动触发分割
    SPLIT_LOG();
    
    LOG_INFO("Log after split");
    
    // 检查原文件是否存在（可能已被压缩）
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    
    // 应该有一个新的日志文件（带时间戳）
    std::vector<std::string> files;
    LS(testDir, files);
    ASSERT_TRUE(files.size() >= 1);
    
    test_common::cleanupTestDir(testDir);
}

void test_log_split_by_time()
{
    std::string testDir = test_common::getTestTempDir();
    std::string logFile = testDir + "/test.log";
    test_common::cleanupTestDir(testDir);
    
    MKDIR(testDir);
    SAVE_LOG(logFile);
    SET_SAVE(true);
    SET_LOG_SPLIT(true);
    SET_LOG_SPLIT_BY_TIME(500);  // 500毫秒后自动分割
    
    LOG_INFO("Log before time split");
    
    // 等待超过分割时间
    std::this_thread::sleep_for(std::chrono::milliseconds(600));
    
    LOG_INFO("Log after time split");
    
    // 检查文件
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    std::vector<std::string> files;
    LS(testDir, files);
    ASSERT_TRUE(files.size() >= 1);
    
    test_common::cleanupTestDir(testDir);
}

void test_log_auto_compress()
{
    std::string testDir = test_common::getTestTempDir();
    std::string logFile = testDir + "/test.log";
    test_common::cleanupTestDir(testDir);
    
    MKDIR(testDir);
    SAVE_LOG(logFile);
    SET_SAVE(true);
    SET_LOG_SPLIT(true);
    SET_LOG_AUTO_COMPRESS(true);
    
    LOG_INFO("Log before split and compress");
    
    // 手动触发分割（应该自动压缩）
    SPLIT_LOG();
    
    LOG_INFO("Log after split");
    
    // 检查压缩文件是否存在
    std::this_thread::sleep_for(std::chrono::milliseconds(200));
    std::vector<std::string> files;
    LS(testDir, files);
    
    // 应该至少有一个文件（可能是压缩的）
    ASSERT_TRUE(files.size() >= 1);
    
    test_common::cleanupTestDir(testDir);
}

int main()
{
    auto& runner = test_common::TestRunner::getInstance();
    runner.reset();
    
    std::cout << "=== Running Log Module Tests ===" << std::endl;
    
    runner.runTest("test_log_basic", test_log_basic);
    runner.runTest("test_log_format", test_log_format);
    runner.runTest("test_log_once", test_log_once);
    runner.runTest("test_log_ctrl", test_log_ctrl);
    runner.runTest("test_save_log", test_save_log);
    runner.runTest("test_log_split_manual", test_log_split_manual);
    runner.runTest("test_log_split_by_time", test_log_split_by_time);
    runner.runTest("test_log_auto_compress", test_log_auto_compress);
    
    std::cout << "\n=== Test Results ===" << std::endl;
    std::cout << "Total: " << runner.getTotal() << std::endl;
    std::cout << "Passed: " << runner.getPassed() << std::endl;
    std::cout << "Failed: " << runner.getFailed() << std::endl;
    
    return runner.getFailed() == 0 ? 0 : 1;
}

